/**
 * Copyright (c) 2015-2020, wss 王山山
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wss.conversion.config;

import java.util.List;
import java.util.Map;

import com.jfinal.log.JdkLoggerFactory;
import com.jfinal.log.Logger;
import com.wss.utils.BeanUtil;
import com.wss.utils.Constants;
import com.wss.utils.JsEngineUtil;
import com.wss.utils.ReflectionUtil;
import com.wss.utils.StringUtil;

/**
 * 解析config.js配置文件
 * 
 * @author wss
 *
 */
class ConfigParse {
	private static final Logger LOG = new JdkLoggerFactory().getLogger(ConfigParse.class);
	
	private String configFile;
	
	ConfigParse(String configFile) {
		this.configFile = configFile;
	}
	
	ApplicationConfig parse() {
		Object config = null;
		// 如果读取配置文件发生错误，就是用默认的配置
		try {
			config = JsEngineUtil.eval(configFile);
		} catch(Exception e) {
			LOG.error("Not read the content of config.js，and will use default configuration");
		}
		ApplicationConfig applicationConfig = new ApplicationConfig();
		Database database = null;
		Main main = null;
		Web web = null;
		if (config == null) {
			database = new Database();
			main = new Main();
			web = new Web();
		}
		else {
			database = getConfigItem(config, "database", Database.class);
			main = getConfigItem(config, "main", Main.class);
			web = getConfigItem(config, "web", Web.class);
		}
		applicationConfig.setDatabase(database);
		applicationConfig.setMain(main);
		applicationConfig.setWeb(web);
		return applicationConfig;
	}
	
	private <T> T getConfigItem(Object config, String itemName, Class<T> configItemClass) {
		T configItem = ReflectionUtil.newInstance(configItemClass);
		List<String> fieldNames = ReflectionUtil.getFieldNames(configItemClass);
		fieldNames.forEach(e -> {
			Object obj = getItem(config, itemName + Constants.DOT + e);
			if (isEffictiveItem(obj)) {
				BeanUtil.set(configItem, e, obj);
			}
		});
		return configItem;
	}
	
	private boolean isEffictiveItem(Object obj) {
		if (obj == null) {
			return false;
		}
		else {
			if (obj instanceof String) {
				return StringUtil.isNotBlank((String) obj);
			}
			else {
				return true;
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private Object getItem(Object config, String itemName) {
		String[] itemNames = itemName.split("\\.");
		Object obj =  null;
		for (String item : itemNames) {
			Map<String, Object> map = (Map<String, Object>) config;
			obj = map.get(item);
			if (obj == null) {
				break;
			}
			config = obj;
		}
		return obj;
	}
}
